/*
    This file is part of the open source IVMP-MySQL project.

    IVMP-MySQL is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    IVMP-MySQL is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with IVMP-MySQL.  If not, see <http://www.gnu.org/licenses/>.
*/

/*
	File: Functions.cpp

	Description:
		Contains the function definitions for Functions.h (see documentation
		of that file for more information).
*/

#include <Functions.h>
#include <Logger.h>
#include <HandleManager.h>

int plugin_mysql_debug(HSQUIRRELVM S)
{
	int debug;

	CHECK_PARAMS(1);
	GET_INTEGER(1, debug);

	if (debug == 1)
		Logger::Initialise();

	return 1;
}

int plugin_mysql_connect(HSQUIRRELVM S)
{
	const char* host;
	const char* username;
	const char* password;
	const char* database;
	int port = 3306;

	CHECK_PARAMS(4);
	GET_STRING(1, host);
	GET_STRING(2, username);
	GET_STRING(3, password);
	GET_STRING(4, database);

	if (GET_PARAMCOUNT() >= 5)
	{
		GET_INTEGER(5, port);
	}

	MySQLHandle* handle = new MySQLHandle(host, username, password, database, port);

	if (!handle->isValid())
	{
		Logger::OutFormatConsole("ERROR: mysql_connect(%s, %s, %s, %s) on port %i failed!", host, username, password, database, port);
		delete handle;
		sq_pushinteger(S, 0);
		return 1;
	}

	int id = HandleManager::AddHandle(handle);

	if (id == 0)
	{
		Logger::Out("ERROR: Can not create any more MySQL handles, limit reached.", true);
		delete handle;
		sq_pushinteger(S, 0);
		return 1;
	}

	Logger::OutFormat("MySQL connection successful on handle %i.", id);
	sq_pushinteger(S, id);
	return 1;
}

int plugin_mysql_close(HSQUIRRELVM S)
{
	int id;

	CHECK_PARAMS(1);
	GET_INTEGER(1, id);

	HandleManager::RemoveHandle(id);
	return 1;
}

int plugin_mysql_errno(HSQUIRRELVM S)
{
	int id;

	CHECK_PARAMS(1);
	GET_INTEGER(1, id);

	MySQLHandle* handle = HandleManager::GetHandle(id);

	if (handle == NULL)
		return 1;

	sq_pushinteger(S, handle->getLastError());
	return 1;
}

int plugin_mysql_ping(HSQUIRRELVM S)
{
	int id;

	CHECK_PARAMS(1);
	GET_INTEGER(1, id);

	MySQLHandle* handle = HandleManager::GetHandle(id);

	if (handle == NULL)
	{
		sq_pushinteger(S, -1);
		return 1;
	}

	sq_pushinteger(S, handle->ping());
	return 1;
}

int plugin_mysql_query(HSQUIRRELVM S)
{
	int id;
	const char* query;

	CHECK_PARAMS(2);
	GET_INTEGER(1, id);
	GET_STRING(2, query);

	MySQLHandle* handle = HandleManager::GetHandle(id);

	if (handle == NULL)
	{
		sq_pushbool(S, false);
		return 1;
	}

	sq_pushbool(S, handle->executeQuery(query));
	return 1;
}

int plugin_mysql_store_result(HSQUIRRELVM S)
{
	int id;

	CHECK_PARAMS(1);
	GET_INTEGER(1, id);

	MySQLHandle* handle = HandleManager::GetHandle(id);

	if (handle == NULL)
	{
		sq_pushbool(S, false);
		return 1;
	}

	sq_pushbool(S, handle->storeResult());
	return 1;
}

int plugin_mysql_free_result(HSQUIRRELVM S)
{
	int id;

	CHECK_PARAMS(1);
	GET_INTEGER(1, id);

	MySQLHandle* handle = HandleManager::GetHandle(id);

	if (handle == NULL)
	{
		sq_pushbool(S, false);
		return 1;
	}

	sq_pushbool(S, handle->freeResult());
	return 1;
}

int plugin_mysql_num_rows(HSQUIRRELVM S)
{
	int id;

	CHECK_PARAMS(1);
	GET_INTEGER(1, id);

	MySQLHandle* handle = HandleManager::GetHandle(id);

	if (handle == NULL)
	{
		sq_pushinteger(S, -1);
		return 1;
	}

	sq_pushinteger(S, handle->getResultRowCount());
	return 1;
}

int plugin_mysql_num_fields(HSQUIRRELVM S)
{
	int id;

	CHECK_PARAMS(1);
	GET_INTEGER(1, id);

	MySQLHandle* handle = HandleManager::GetHandle(id);

	if (handle == NULL)
	{
		sq_pushinteger(S, -1);
		return 1;
	}

	sq_pushinteger(S, handle->getResultFieldCount());
	return 1;
}

int plugin_mysql_fetch_row(HSQUIRRELVM S)
{
	int id;

	CHECK_PARAMS(1);
	GET_INTEGER(1, id);

	MySQLHandle* handle = HandleManager::GetHandle(id);

	if (handle == NULL)
	{
		sq_pushbool(S, false);
		return 1;
	}

	sq_pushbool(S, handle->fetchResultRow());
	return 1;
}

int plugin_mysql_fetch_field_row(HSQUIRRELVM S)
{
	int id;
	int fieldIndex;

	CHECK_PARAMS(2);
	GET_INTEGER(1, id);
	GET_INTEGER(2, fieldIndex);

	MySQLHandle* handle = HandleManager::GetHandle(id);

	if (handle == NULL)
	{
		sq_pushinteger(S, 0);
		return 1;
	}

	const char* data = handle->fetchFieldFromRow(static_cast<unsigned int>(fieldIndex));

	if (data == NULL)
	{
		sq_pushinteger(S, 0);
		return 1;
	}

	sq_pushstring(S, data, strlen(data));
	return 1;
}

int plugin_mysql_escape_string(HSQUIRRELVM S)
{
	int id;
	const char* string;

	CHECK_PARAMS(2);
	GET_INTEGER(1, id);
	GET_STRING(2, string);

	MySQLHandle* handle = HandleManager::GetHandle(id);

	if (handle == NULL)
	{
		sq_pushinteger(S, 0);
		return 1;
	}

	char* escaped = new char[strlen(string) * 2 + 1];
	mysql_real_escape_string(handle->getConnection(), escaped, string, strlen(string));

	sq_pushstring(S, escaped, strlen(escaped));
	return 1;
}